/**
 * @file videocapturer.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2022-10-20
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#ifndef SRC_CAMERA_VIDEOCAPTURER_H_
#define SRC_CAMERA_VIDEOCAPTURER_H_

#include <QObject>
#include <QThread>
#include <memory>

struct AVFormatContext;
struct AVCodecContext;
struct AVFrame;
struct SwsContext;

// 相机图像抓取对象
class VideoCapturer : public QThread {
  Q_OBJECT
    Q_PROPERTY(bool convert  WRITE setConvert)

 public:
  explicit VideoCapturer(QObject* parent = nullptr, bool convert2rgb = false);
  ~VideoCapturer();

  // 打开相机设备
  Q_INVOKABLE bool open(const QString& device_name);

  // 停止相机画面帧抓取，线程也将停止
  Q_INVOKABLE void close();

  // 设置是否需要yuv转rgb
  void setConvert(bool convert) { m_bConvert2Rgb = convert; }

 protected:
  // 线程回调
  void run() override;

 private:
  // 打开解码器
  bool openDecoder();

  // 从相机抓取图像
  void read();

  // 清理资源
  void clear();

  // yuv转rgb
  bool yuv2rgb(AVFrame* in, AVFrame** out);

 signals:
  // 发送图像帧
  void appending_frame(std::shared_ptr<AVFrame>);

  // 发送错误信息
  void error(const QString& err);

 private:
  AVFormatContext* m_pCtx{nullptr};
  AVCodecContext* m_pDecoderCtx{nullptr};
  SwsContext* m_pConvert{nullptr};

  std::atomic_bool m_bRunning{false};

  bool m_bConvert2Rgb{false};
};

#endif  // SRC_CAMERA_VIDEOCAPTURER_H_
